// main.go
package main

import (
	//"bytes"
	"fmt"
	//"io"
	"code.google.com/p/goconf/conf"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"runtime"
	"time"
)

var Basedir string
var WorkerCount int = 0
var MaintainerTick time.Duration = time.Second * 20
var ScoreReduce int = 0
var ListenAddress string = ""

func readconfig(filename string) error {
	c, err := conf.ReadConfigFile(filename)

	if err == nil {
		Basedir, _ = c.GetString("default", "webroot")
		WorkerCount, _ = c.GetInt("default", "workercount")
		maintaintick, _ := c.GetString("default", "maintainertick")
		MaintainerTick, _ = time.ParseDuration(maintaintick)
		ScoreReduce, _ = c.GetInt("default", "scorereduce")
		ListenAddress, _ = c.GetString("default", "listen")
	}
	return err
}

func main() {
	if len(os.Args) < 2 {
		log.Println("No config file specified, dying")
		return
	}

	log.SetOutput(ioutil.Discard)

	err := readconfig(os.Args[1])
	log.Println(Basedir, WorkerCount, MaintainerTick, ScoreReduce, ListenAddress)

	if err != nil {
		log.Println("Config file nonexistant, dying")
		return
	}

	fmt.Println("Hello World!")
	http.HandleFunc("/", handler)

	runtime.GOMAXPROCS(WorkerCount + 1)

	for x := 0; x <= WorkerCount; x++ {

	}

	StartCacheMaintainer()
	http.ListenAndServe(ListenAddress, nil)
}

func handler(resp http.ResponseWriter, req *http.Request) {
	fmt.Println(req.RequestURI)

	_, file := path.Split(req.RequestURI)

	hai := Cacheworkitem{}
	hai.command = CACHE_FETCH
	hai.relpath = path.Clean(req.RequestURI)
	hai.name = file
	hai.retchan = make(chan *Cacheitem)

	CacheWorkerChannel <- hai
	cacheitem := <-hai.retchan

	if cacheitem.faulty == nil {
		if cacheitem.incache && cacheitem.cacheable {
			log.Println("Loading", cacheitem.name, "from cache")
			resp.Header().Add("Content-Type", cacheitem.contenttype)
			resp.Header().Add("X-Cache", fmt.Sprint("HIT: Loaded from cache. Score ", cacheitem.score))
			resp.Write(cacheitem.data)
		} else {
			log.Println("Serving", cacheitem.name, "directly")
			resp.Header().Add("X-Cache", fmt.Sprint("MISS: Item wasnt in top 100. Score ", cacheitem.score))
			http.ServeFile(resp, req, path.Join(Basedir, path.Clean(req.RequestURI)))
		}
	} else {
		resp.WriteHeader(404)
		resp.Write([]byte(cacheitem.faulty.Error()))
	}

}
